﻿using System.Collections.Generic;
using System;
using System.ComponentModel;

public class EventManager
{
    static EventDispatcher dispatcher = new EventDispatcher();
    public static void AddListener(string eventType, EventListener.EventHandler eventHandler)
    {
        dispatcher.AddListener(eventType, eventHandler);
    }

    public static void RemoveListener(string eventType, EventListener.EventHandler eventHandler)
    {
        dispatcher.RemoveListener(eventType, eventHandler);
    }

    public static void DispatchEvent(string eventType, params object[] args)
    {
        dispatcher.DispatchEvent(eventType, args);
    }
    public static bool HasListener(string eventType)
    {
        return dispatcher.HasListener(eventType);
    }

    public static void Clear()
    {
        dispatcher.Clear();

    }
}

public class EventDispatcher
{
    Dictionary<string, EventListener> dic = new Dictionary<string, EventListener>();
    public void AddListener(string eventType, EventListener.EventHandler eventHandler)
    {
        EventListener listener;
        if (!dic.TryGetValue(eventType, out listener))
        {
            listener = new EventListener();
            dic.Add(eventType, listener);
        }
        listener.handler += eventHandler;
    }

    public void RemoveListener(string eventType, EventListener.EventHandler eventHandler)
    {
        if (dic.ContainsKey(eventType))
        {
            dic[eventType].handler -= eventHandler;
        }
    }
    public void DispatchEvent(string eventType, params object[] args)
    {
        EventListener invoker;
        if (dic.TryGetValue(eventType, out invoker))
        {
            EventArgs evt;
            if (args == null || args.Length == 0)
            {
                evt = new EventArgs(eventType);
            }
            else
            {
                evt = new EventArgs(eventType, args);
            }
            invoker.Invoke(evt);
        }
    }
    public bool HasListener(string eventType)
    {
        return dic.ContainsKey(eventType);
    }

    public void Clear()
    {
        foreach (EventListener value in dic.Values)
        {
            value.Clear();
        }
        dic.Clear();
    }

}

public class EventListener
{
    public delegate void EventHandler(EventArgs eventArgs);
    public EventHandler handler;
    public void Invoke(EventArgs eventArgs)
    {
        if (eventArgs != null)
        {
            handler.Invoke(eventArgs);
        }
    }
    public void Clear()
    {
        handler = null;
    }
}

public class EventArgs
{

    public readonly string type;
    public readonly object[] args;

    public EventArgs(string type)
    {
        this.type = type;
    }

    public EventArgs(string type, params object[] args)
    {
        this.type = type;
        this.args = args;
    }
}
